package com.luojing.myThread.cyclicbarrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * 线程同步计数器
 * @author luojing
 * @create 2018/08/25 下午3:51
 **/
public class CyclicBarrierDemo {

  public static void main(String[] args) {
    int count = 10;
    final CyclicBarrier cyclicBarrier = new CyclicBarrier(count,new TotalTask());

    for(int i = 1;i <= count;i++){
      new BillTask("订单:" + i,(i * 1000),cyclicBarrier).start();
    }

    System.out.println("主线程运行完毕");
  }

  static class TotalTask extends Thread {
    @Override
    public void run(){
      System.out.println("汇总执行");
    }
  }

  static class BillTask extends Thread{
    private String name;

    private CyclicBarrier cyclicBarrier;

    private long time;

    public BillTask(String name,long time,CyclicBarrier cyclicBarrier){
      this.name = name;
      this.time = time;
      this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
      System.out.println("订单:" + name + "运算开始");
      if(time == 5000){
        System.out.println("重置屏障");
        try {
          Thread.sleep(2000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        cyclicBarrier.reset();
      }
      try {
        Thread.sleep(time);
        System.out.println("订单:" + name + "运算完成,等待其他线程");
        try {
          try {
            cyclicBarrier.await(20, TimeUnit.SECONDS);
          } catch (TimeoutException e) {
            e.printStackTrace();
          }
        } catch (BrokenBarrierException e) {
          e.printStackTrace();
        }
        System.out.println("其他线程运行完成,继续运行:" + name + "...");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}
